package com.sinosoft.hydra.um.services.component.dataimport;

import com.sinosoft.hydra.um.services.component.dataimport.validators.Validator;
import cn.com.sinux.spring.utils.DateUtils;
import org.apache.commons.lang.time.DateFormatUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Administrator on 2015/1/23.
 */
public class CellDataResolver {

    private List<Validator> validators = new ArrayList<Validator>();
    private String resolveType;

    private final String timePatterns[] = new String[]{"yyyy-MM-dd", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyyMMdd", "yyyyMMddHHmm", "yyyyMMddHHmmss"};

    private DataResult<Date> parseDate(Object obj) {
        try {
            if (obj instanceof String) {
                return DataResult.SUCCESS(DateUtils.parseDate((String) obj, timePatterns));
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS(new Date(((Double) obj).longValue()));
            } else if (obj instanceof Date) {
                return DataResult.SUCCESS((Date) obj);
            } else if (obj instanceof Boolean) {
                return DataResult.ERROR("数据不是有效的时间类型");
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的时间类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<String> parseString(Object obj) {
        try {
            if (obj instanceof String) {
                return DataResult.SUCCESS((String) obj);
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS(String.valueOf(obj));
            } else if (obj instanceof Date) {
                return DataResult.SUCCESS(DateFormatUtils.format((Date) obj, "yyyy/MM/dd HH:mm:ss"));
            } else if (obj instanceof Boolean) {
                return DataResult.SUCCESS((Boolean) obj ? "true" : "false");
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的字符串类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<Double> parseDouble(Object obj) {
        try {
            if (obj instanceof String) {
                return DataResult.SUCCESS(Double.valueOf(((String) obj).trim()));
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS((Double) obj);
            } else if (obj instanceof Date) {
                return DataResult.SUCCESS((double) ((Date) obj).getTime());
            } else if (obj instanceof Boolean) {
                return (Boolean) obj ? DataResult.SUCCESS(1d) : DataResult.SUCCESS(0d);
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的小数类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<BigDecimal> parseDecimal(Object obj) {
        DataResult<Double> doubleDataResult = parseDouble(obj);
        if (!doubleDataResult.isValid()) {
            return DataResult.ERROR(doubleDataResult.getError());
        }
        try {
            Double value = doubleDataResult.getSource();
            if (value != null) {
                return DataResult.SUCCESS(BigDecimal.valueOf(value));
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的小数类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<Boolean> parseBoolean(Object obj) {
        try {
            if (obj instanceof String) {
                return DataResult.SUCCESS(Boolean.valueOf(((String) obj).trim()));
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS(((Double) obj) > 0);
            } else if (obj instanceof Date) {
                return DataResult.ERROR("数据不是有效的BOOLEAN类型");
            } else if (obj instanceof Boolean) {
                return DataResult.SUCCESS((Boolean) obj);
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的BOOLEAN类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<Integer> parseInteger(Object obj) {
        try {
            if (obj instanceof String) {
                return DataResult.SUCCESS(Integer.valueOf(((String) obj).trim()));
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS(((Double) obj).intValue());
            } else if (obj instanceof Date) {
                return DataResult.SUCCESS((int) ((Date) obj).getTime());
            } else if (obj instanceof Boolean) {
                return (Boolean) obj ? DataResult.SUCCESS(1) : DataResult.SUCCESS(0);
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的整数类型");
        }
        return DataResult.SUCCESS(null);
    }

    private DataResult<List<String>> parseArray(Object obj) {
        try {
            if (obj instanceof String) {
                String value = (String) obj;
                return DataResult.SUCCESS(Arrays.asList(value.trim().split(",")));
            } else if (obj instanceof Double) {
                return DataResult.SUCCESS(Collections.singletonList(String.valueOf(obj)));
            } else if (obj instanceof Date) {
                return DataResult.SUCCESS(Collections.singletonList(DateFormatUtils.format((Date) obj, "yyyy/MM/dd HH:mm:ss")));
            } else if (obj instanceof Boolean) {
                return DataResult.SUCCESS(Collections.singletonList((Boolean) obj ? "true" : "false"));
            }
        } catch (Exception ex) {
            return DataResult.ERROR("数据不是有效的数组类型");
        }
        return DataResult.SUCCESS(Collections.<String>emptyList());
    }

    public DataResult resolveCell(Object cellData) {
        if(cellData == null){
            return DataResult.SUCCESS(null);
        }
        Object data = cellData;
        if ("int".equals(this.resolveType)) {
            return parseInteger(data);
        } else if ("date".equals(this.resolveType)) {
            return parseDate(data);
        }else if("double".equals(this.resolveType)){
            return parseDouble(data);
        }else if("string".equals(this.resolveType)){
            return parseString(data);
        }else if("array".equals(this.resolveType)){
            return  parseArray(data);
        }else if("boolean".equals(this.resolveType)){
            return parseBoolean(data);
        }else if("bigDecimal".equals(this.resolveType)){
            return parseDecimal(data);
        }else{
           return DataResult.SUCCESS(null);
        }
    }

    public List<Validator> getValidators() {
        return validators;
    }

    public CellDataResolver(String resolveType, List<Validator> validators) {
        this.resolveType = resolveType;
        this.validators = validators;
    }

    public CellDataResolver(String resolveType) {
        this.resolveType = resolveType;
    }
}
